package com.zw.myservice.service;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.GestureDescription;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 辅助服务模拟微信发送消息
 * @Author: ltt
 * @CreateDate: 2021/9/30 10:12
 */
public class MyAccessibilityService extends AccessibilityService {


    public static MyAccessibilityService mService;

    private static final String TAG=MyAccessibilityService.class.getSimpleName();

    private List<AccessibilityNodeInfo> ids=new ArrayList<>();

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        mService = this;
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {

    }

    @Override
    public void onInterrupt() {

    }


    /**
     * 根据指定文字字符查找页面对应内容
     *
     * @param text
     * @return
     */
    public AccessibilityNodeInfo findByContent(String text) {
        if (mService == null) {
            return null;
        }
        try {
            //拿到跟节点
            AccessibilityNodeInfo rootInfo = getRootInActiveWindow();
            //当页面什么都没有，或者空白页面，节点信息返回为空
            if (rootInfo == null || TextUtils.isEmpty(rootInfo.getClassName())) {
                return null;
            }
            //开始寻找目标节点
            if (rootInfo.getChildCount() > 0) {
                return findByContent(rootInfo, text);
            }

        } catch (Exception e) {
        }

        return null;

    }

    public AccessibilityNodeInfo findByContent(AccessibilityNodeInfo rootInfo, String text) {
        if (rootInfo == null) return null;
        //开始遍历子节点
        for (int i = 0; i < rootInfo.getChildCount(); i++) {
            AccessibilityNodeInfo child = rootInfo.getChild(i);
            try {
                if (child.findAccessibilityNodeInfosByText(text).size() > 0) {
                    for (AccessibilityNodeInfo view : child.findAccessibilityNodeInfosByText(text)) {
                        return view;
                    }
                    return child;
                }
            } catch (NullPointerException e) {
            }
            findByContent(child, text);//递归一直找一层层的全部遍历
        }
        return null;
    }

    /***
     * 根据ViewID查找页面某一个View事件
     * @param id
     * @return
     */
    public AccessibilityNodeInfo findByID(String id) {
        if (mService == null) return null;
        try {
            //拿到根节点
            AccessibilityNodeInfo rootInfo = getRootInActiveWindow();
            if (rootInfo == null || TextUtils.isEmpty(rootInfo.getClassName())) {
                return null;
            }
            //开始找目标节点，这里拎出来细讲，直接往下看正文
            if (rootInfo.getChildCount() > 0) {
                return findByID(rootInfo, id);

            }
        } catch (Exception e) {

        }
        return null;
    }

    public AccessibilityNodeInfo findByID(AccessibilityNodeInfo rootInfo, String text) {
        if (rootInfo == null) return null;
        for (int i = 0; i < rootInfo.getChildCount(); i++) {
            AccessibilityNodeInfo child = rootInfo.getChild(i);
            try {
                if (child.findAccessibilityNodeInfosByViewId(text).size() > 0) {
                    for (AccessibilityNodeInfo view : child.findAccessibilityNodeInfosByViewId(text)) {
                        return view;
                    }
                    return child;
                }
            } catch (NullPointerException ignored) {
                System.out.println("异常抛出"+ignored.getMessage());
            }
            findByID(child, text);//递归一直找一层层的全部遍历
        }
        return null;
    }

    /**
     * 遍历整个页面所有子节点,用于测试
     */
    public void printAllTrees() {
        if (mService == null) return;
        try {
            //拿到根节点
            AccessibilityNodeInfo rootInfo = getRootInActiveWindow();
            if (rootInfo == null || TextUtils.isEmpty(rootInfo.getClassName())) {
                return;
            }
            Rect rect = new Rect();
            rootInfo.getBoundsInScreen(rect);
            String id = rootInfo.getViewIdResourceName();
            if (TextUtils.isEmpty(id)) id = "no id";
            Log.e(TAG, rootInfo.getClassName().toString() + "----" + id/*+"----"+text*/ + "  " + rect);
            //开始找目标节点，这里拎出来细讲，直接往下看正文
            if (rootInfo.getChildCount() > 0) {
                printTree(rootInfo);
            }
//            }
        } catch (Exception e) {

        }
    }

    /**
     * 循环遍历子节点
     *
     * @param rootInfo
     */
    private void printTree(AccessibilityNodeInfo rootInfo) {
        int count = rootInfo.getChildCount();
        for (int i = 0; i < count; i++) {
            AccessibilityNodeInfo child = rootInfo.getChild(i);
            Rect rect = new Rect();
            child.getBoundsInScreen(rect);
            String id = child.getViewIdResourceName();
            if (TextUtils.isEmpty(id)) id = "no id";
            String text = "no text";
            if (child.getText() != null)
                text = child.getText().toString();
            Log.e(TAG, child.getClassName().toString() + "--------------" + text + "-----------" + rect);
            if (child.getChildCount() > 0) {
                printTree(child);
            }
        }
    }

    /**
     * 模拟点击事件
     * @param clickable
     */
    public void performClick(AccessibilityNodeInfo clickable) {
        performClick(clickable, false);
    }

    /**
     *
     * @param clickable 找到的事件
     * @param useGusture 强制点击 默认不设置执行以上方法
     */
    public void performClick(AccessibilityNodeInfo clickable, boolean useGusture) {
        if (clickable == null) return;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && useGusture) {
            Rect rect = new Rect();
            clickable.getBoundsInScreen(rect);
            float x = rect.left + (rect.right - rect.left) / 2.0f;
            float y = rect.top + (rect.bottom - rect.top) / 2.0f;
            Log.e(TAG, "click point:x->" + x + " y->" + y);
//            if(!ZipFilesUtil.gueture(x,y)){
            Path mPath = new Path();//线性的path代表手势路径,点代表按下,封闭的没用
            mPath.moveTo(x, y);
            mService.dispatchGesture(new GestureDescription.Builder().addStroke(new GestureDescription.StrokeDescription
                    (mPath, 0, 50L)).build(), null, null);
//            }


            return;
        }
        clickable.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
        clickable.performAction(AccessibilityNodeInfo.ACTION_CLICK);
    }

    /**
     * 当点击聊天板块中的消息点击事件，
     * @param clickable
     * @param useGusture
     */
    public void performChartClick(AccessibilityNodeInfo clickable, boolean useGusture) {
        if (clickable == null) return;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && useGusture) {
            Rect rect = new Rect();
            clickable.getBoundsInScreen(rect);
            float x = rect.left + (rect.right - rect.left) / 2.50f;
            float y = rect.top + (rect.bottom - rect.top) / 2.50f;
            Log.e(TAG, "click point:x->" + x + " y->" + y);
//            if(!ZipFilesUtil.gueture(x,y)){
            Path mPath = new Path();//线性的path代表手势路径,点代表按下,封闭的没用
            mPath.moveTo(x, y);
            mService.dispatchGesture(new GestureDescription.Builder().addStroke(new GestureDescription.StrokeDescription
                    (mPath, 0, 50L)).build(), null, null);
//            }


            return;
        }
        clickable.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
        clickable.performAction(AccessibilityNodeInfo.ACTION_CLICK);
    }

    /**
     * 执行点击返回事件
     */
    public void performGlobalBack() {
        performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
    }
    public void dispatchGestureClick(int x, int y) {
        dispatchGestureClick(0, x, y);
        //手势开始时间比如立即开始
        //手势总时长比如

    }

    public void dispatchGestureClick(int start, int x, int y) {
        if (mService == null) return;
        //发送一个点击事件
        Path mPath = new Path();//线性的path代表手势路径,点代表按下,封闭的没用
        mPath.moveTo(x, y);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mService.dispatchGesture(new GestureDescription.Builder().addStroke(new GestureDescription.StrokeDescription
                    (mPath, start, 50)).build(), null, null);
        }

        Log.e(TAG, "click point:x->" + x + " y->" + y);
        //手势开始时间比如立即开始
        //手势总时长比如

    }

    /***
     * 得到所有节点
     * @return
     */
    public List<AccessibilityNodeInfo> getAllNodes() {
        ids.clear();
        if (mService == null) return ids;

        try {
            //拿到根节点
            AccessibilityNodeInfo rootInfo = getRootInActiveWindow();
            if (rootInfo == null || TextUtils.isEmpty(rootInfo.getClassName())) {
                return ids;
            }
            if (rootInfo.getClassName() != null)
                ids.add(rootInfo);
            if (rootInfo.getChildCount() > 0) {

                getAllNodes(rootInfo);
            }
        } catch (Exception e) {

        }
        return ids;
    }
    private void getAllNodes(AccessibilityNodeInfo rootInfo) {

        int count = rootInfo.getChildCount();
        for (int i = 0; i < count; i++) {
            AccessibilityNodeInfo child = rootInfo.getChild(i);
            if (child.getClassName() != null)
                ids.add(child);
            if (child.getChildCount() > 0) {
                getAllNodes(child);
            }
        }
    }
    public static boolean isServerStarted() {
        return mService != null;
    }
}
